package rpa

import (
	"context"
	"crypto/aes"
	"crypto/cipher"
	"encoding/base64"
	"encoding/json"
	"errors"
	"fmt"
	"git.mycaigou.com/gfyx/common/cache"
	"git.mycaigou.com/gfyx/micro-gfyx-api/infrastructure/dto/rpa"
	rpa2 "git.mycaigou.com/gfyx/micro-gfyx-api/infrastructure/repository/rpa"
	"git.mycaigou.com/gfyx/micro-gfyx-api/infrastructure/utils/jwt"
	"git.myscrm.cn/golang/stark/v4"
	"strconv"
	"time"
)

type RccService struct {
	callHandlerMap map[int64]rpa.RpaHandler
	byaiService    ByaiServiceIface
	rpaRepository  rpa2.RpaRepositoryIface
}

// 构造函数
func NewRccService(byaiService ByaiServiceIface, rpaRepository rpa2.RpaRepositoryIface) RccServiceIface {
	handlerMap := make(map[int64]rpa.RpaHandler)
	rccService := &RccService{
		callHandlerMap: handlerMap,
		byaiService:    byaiService,
		rpaRepository:  rpaRepository,
	}

	rccService.initConfig()
	return rccService
}

// 初始化
func (s *RccService) initConfig() {
	s.callHandlerMap[rpa.RCC_WEB_POST_1001] = s.cmdPostCallPhone
	s.callHandlerMap[rpa.RCC_WEB_POST_1002] = s.cmdPostProjectData
	s.callHandlerMap[rpa.RCC_WEB_GET_2001] = s.cmdGetProjectData
	s.callHandlerMap[rpa.RCC_WEB_GET_2002] = s.cmdGetDecrpytRccData
	s.callHandlerMap[rpa.RCC_WEB_GET_2003] = s.cmdGetCheckDataExist
}

func (s *RccService) GetCmdHandlers() map[int64]rpa.RpaHandler {
	return s.callHandlerMap
}

type CmdPostCallPhoneData struct {
	// 联系电话
	Phone string `json:"phone"`
	// 客户名称
	Name string `json:"name"`
}

// RCC_WEB_POST_1001
func (s *RccService) cmdPostCallPhone(ctx context.Context, protoVersion int8, rpaVersion string, param *rpa.RpaMessage) (interface{}, error) {
	authInfo, err := jwt.GetAuthInfo(ctx)
	if err != nil {
		return nil, err
	}

	msgData := &rpa.RpaMessageData1001{}
	err = json.Unmarshal([]byte(param.Data), msgData)
	if err != nil {
		return nil, err
	}

	stark.Logger.Infof(ctx, "cmdPostCallPhone-callPhoneParams: %+v, param.Data: %+v", msgData, param.Data)
	if msgData.Phone == "" {
		return nil, errors.New("cmdPostCallPhone-1001-非法的数据格式")
	}

	// 1. 检查外呼任务是否已经存在，不存在需要创建任务
	cacheRedis, _ := cache.Redis()
	cacheKey := fmt.Sprintf("gfyx-%s", authInfo.TenantCode)
	taskIdStr, err := cacheRedis.Get(ctx, cacheKey)
	if err != nil {
		return nil, err
	}

	var taskId int64
	var isFirstCreate = false
	if taskIdStr == "" {
		isFirstCreate = true
		taskId, err = s.byaiService.CreateByAiTask(ctx, &rpa.ByAiTask{
			CallJobName:      fmt.Sprintf("外呼任务-%s-%s", authInfo.TenantCode, time.Now().Format("20060102")),
			CallJobType:      2,
			CompanyId:        rpa.COMPANYID,
			ConcurrencyNum:   4,
			ConcurrencyQuota: 2,
			Remark:           "rpa调度自动创建任务",
			RobotDefId:       333099,
			UserPhoneIds:     []int32{274442},
			PermitRepeatNum:  true,
		})
		if err != nil {
			return nil, err
		}

		// 存储taskid
		_, err = cacheRedis.Set(ctx, cacheKey, fmt.Sprintf("%d", taskId), true, 356*24*3600)
		if err != nil {
			return nil, err
		}
	} else {
		taskId1, err := strconv.Atoi(taskIdStr)
		if err != nil {
			return nil, err
		}
		taskId = int64(taskId1)
	}

	// 2. 检查机器人是否已启动
	if isFirstCreate == true {
		_, err := s.byaiService.ExecuteByAiTask(ctx, taskId, rpa.COMPANYID, 1)
		if err != nil {
			stark.Logger.Infof(ctx, "cmdPostCallPhone-ExecuteByAiTask-err: %+v", err)
			return nil, err
		}
	}

	// 3. 增加数据到外呼任务
	customerInfo := &rpa.CustomerInfoItem{
		Name:       msgData.Name,
		Phone:      msgData.Phone,
		Properties: nil,
	}

	list := make([]*rpa.CustomerInfoItem, 0)
	list = append(list, customerInfo)
	_, err = s.byaiService.ImportCustomerToTask(ctx, taskId, rpa.COMPANYID, list)
	if err != nil {
		stark.Logger.Infof(ctx, "cmdPostCallPhone-ImportCustomerToTask-err: %+v", err)
		return nil, err
	}

	return customerInfo, nil
}

// RCC_WEB_POST_1002
func (s *RccService) cmdPostProjectData(ctx context.Context, protoVersion int8, rpaVersion string, param *rpa.RpaMessage) (interface{}, error) {
	authInfo, err := jwt.GetAuthInfo(ctx)
	if err != nil {
		return nil, err
	}

	if param.Data == "" {
		return nil, errors.New("cmdPostProjectData-1002-非法的数据格式")
	}

	// todo: 暂时存储在缓存
	//ruuid := uuid.New().String()
	//cacheRedis, _ := cache.Redis()
	//cacheKey := fmt.Sprintf("gfyx-rpa-rcc-%s-%s", authInfo.TenantCode, ruuid)
	//_, err = cacheRedis.Set(ctx, cacheKey, param.Data, true, 365*24*3600)
	//rs, _ := cacheRedis.Get(ctx, cacheKey)
	//stark.Logger.Infof(ctx, "cmdPostProjectData-save, cacheKey=%s, err: %+v, rs: %s", cacheKey, err, rs)
	//if err != nil {
	//	return nil, err
	//}
	flag, err := s.rpaRepository.SaveRpaProjectData(ctx, authInfo.TenantCode, param.Data)
	if err != nil {
		return nil, err
	}
	if !flag {
		return nil, errors.New("项目保存失败")
	}

	return true, nil
}

// RCC_WEB_GET_2001
func (s *RccService) cmdGetProjectData(ctx context.Context, protoVersion int8, rpaVersion string, param *rpa.RpaMessage) (interface{}, error) {
	msgData := &rpa.RpaMessageData2001{}
	err := json.Unmarshal([]byte(param.Data), msgData)
	if err != nil {
		return nil, err
	}

	stark.Logger.Infof(ctx, "cmdGetProjectData: %+v, param.Data: %+v", msgData, param.Data)
	if msgData.Key == "" {
		return nil, errors.New("cmdPostCallPhone-1001-非法的数据格式")
	}

	cacheRedis, _ := cache.Redis()
	rs, err := cacheRedis.Get(ctx, msgData.Key)
	stark.Logger.Infof(ctx, "cmdGetProjectData-save, cacheKey=%s, err: %+v, rs: %s", msgData.Key, err, rs)
	if err != nil {
		return nil, err
	}

	var result interface{}
	err = json.Unmarshal([]byte(rs), &result)
	if err != nil {
		return nil, err
	}

	return result, nil
}

// RCC_WEB_GET_2002
func (s *RccService) cmdGetDecrpytRccData(ctx context.Context, protoVersion int8, rpaVersion string, param *rpa.RpaMessage) (interface{}, error) {
	msgData := &rpa.RpaMessageData2002{}
	err := json.Unmarshal([]byte(param.Data), msgData)
	if err != nil {
		return nil, err
	}

	stark.Logger.Infof(ctx, "cmdGetDecrpytRccData-msgData: %+v, param.Data: %+v", msgData, param.Data)
	if msgData.EncryptedText == "" {
		return nil, errors.New("cmdGetDecrpytRccData-2002-非法的数据格式")
	}

	key := []byte("d6F3Efeqd6F3Efeqd6F3Efeqd6F3Efeq")
	iv := []byte("1234567890123456")

	encrypted, err := base64.StdEncoding.DecodeString(msgData.EncryptedText)
	if err != nil {
		return nil, err
	}

	block, err := aes.NewCipher(key)
	if err != nil {
		fmt.Println(err)
		return nil, err
	}

	stream := cipher.NewCTR(block, iv)
	decrypted := make([]byte, len(encrypted))
	stream.XORKeyStream(decrypted, encrypted)
	text := string(decrypted)

	stark.Logger.Infof(ctx, "cmdGetDecrpytRccData-msgData: param.Data: %+v, text", param.Data, text)
	return text, nil
}

// RCC_WEB_GET_2003
func (s *RccService) cmdGetCheckDataExist(ctx context.Context, protoVersion int8, rpaVersion string, param *rpa.RpaMessage) (interface{}, error) {
	authInfo, err := jwt.GetAuthInfo(ctx)
	if err != nil {
		return nil, err
	}

	if param.Data == "" {
		return nil, errors.New("cmdGetCheckDataExist-2003-非法的数据格式")
	}
	fmt.Println("param.Data:", param.Data)
	var msgData []string
	err = json.Unmarshal([]byte(param.Data), &msgData)
	if err != nil {
		return nil, err
	}
	stark.Logger.Infof(ctx, "cmdGetCheckDataExist-msgData: %+v, param.Data: %+v", msgData, param.Data)

	srcIds, err := s.rpaRepository.CheckRpaProjectExist(ctx, authInfo.TenantCode, msgData)
	if err != nil {
		return nil, err
	}

	return srcIds, nil
}
